use crate::dao::types;
use crate::models::{NewType, TreeNode};
use crate::DbPool;
use crate::{controller::Res, models::Type};
use actix_web::{delete, error, get, post, put, web, Error, HttpResponse, Result};
use std::collections::HashMap;

#[get("/types/")]
pub async fn list(
    tmpl: web::Data<tera::Tera>,
    query: web::Query<HashMap<String, String>>,
    pool: web::Data<DbPool>,
) -> Result<HttpResponse, Error> {
    let conn = pool.get().expect("couldn't get db connection from pool");
    let mut ctx = tera::Context::new();
    let ret = types::get_all(true, &conn).unwrap();
    let nodes = TreeNode::<Type>::new(ret);

    if let Some(id) = query.get("edit") {
        if let Ok(edit_type) = types::get(id.clone(), &conn) {
            ctx.insert("edit_type", &edit_type);
        }
    }

    ctx.insert("types", &nodes);

    let s = tmpl
        .render("admin/type/list.html", &ctx)
        .map_err(|_| error::ErrorInternalServerError("Template error"))?;
    Ok(HttpResponse::Ok().content_type("text/html").body(s))
}

#[delete("/types/")]
pub async fn delete(
    query: web::Query<HashMap<String, String>>,
    pool: web::Data<DbPool>,
) -> HttpResponse {
    let conn = pool.get().expect("couldn't get db connection from pool");

    let res;
    if let Some(id) = query.get("delete") {
        if let Ok(ts) = types::get_all_children(id.clone(), true, &conn) {
            if ts.len() > 0 {
                return HttpResponse::Ok().json(Res::<String>::new_with_error(
                    3,
                    "该分类存在子分类，请先删除所有子分类".to_string(),
                ));
            }
        } else {
            return HttpResponse::Ok().json(Res::<String>::new_with_error(
                4,
                "获取子分类出错".to_string(),
            ));
        }

        if let Ok(ret) = types::delete(id.clone(), &conn) {
            res = Res::new(Some(ret));
            return HttpResponse::Ok().json(res);
        } else {
            return HttpResponse::Ok()
                .json(Res::<String>::new_with_error(1, "删除分类出错".to_string()));
        }
    } else {
        return HttpResponse::Ok().json(Res::<String>::new_with_error(
            2,
            "请在 url 中带上要删除的分类 id".to_string(),
        ));
    }
}

#[post("/types/")]
pub async fn type_add(new_type: web::Json<NewType>, pool: web::Data<DbPool>) -> HttpResponse {
    let conn = pool.get().expect("couldn't get db connection from pool");
    let ret = types::insert(&conn, new_type.0).unwrap();
    HttpResponse::Ok().json(Res::new(Some(ret)))
}

#[put("/types/")]
pub async fn type_edit(new_type: web::Json<NewType>, pool: web::Data<DbPool>) -> HttpResponse {
    let conn = pool.get().expect("couldn't get db connection from pool");
    let ret = types::update(&conn, new_type.0).unwrap();
    HttpResponse::Ok().json(Res::new(Some(ret)))
}
